home *** CD-ROM | disk | FTP | other *** search
- #ifndef LINT
- /* @(#) misc.c 1.7 87/05/03 15:59:33 */
- static char sccsid[]="@(#) misc.c 1.7 87/05/03 15:59:33";
- #endif /* LINT */
-
- /*
- Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- */
- #include "options.h"
- /* Miscellaneous functions needed by Zoo but not by Ooz */
-
- #include "zoo.h"
- #include <stdio.h>
- #include "various.h"
-
- #include "errors.i"
- #include "zoofns.h"
- #ifndef NOSIGNAL
- #include <signal.h>
- #endif
-
- #ifdef NEEDCTYP
- #include <ctype.h>
- #endif
-
- /*
- calc_ofs() is given a string that (supposedly) begins with a string
- of digits. It returns a corresponding numeric value. If no such
- string, it returns zero.
- */
- long calc_ofs(str)
- char *str;
- {
- long retval;
- int status;
- char *p;
- retval = 0L;
- p = str; /* save for error message */
- while (isdigit(*str)) {
- retval = retval * 10L + (*str-'0');
- str++;
- }
- if (*str != '\0')
- prterror ('f', "Invalid number %s\n", p);
- return (retval);
- }
-
- /*
- choosefname() decides which filename to use. If a long filename is present,
- and if the syntax is that of UNIX, MS-DOS or the portable form, we use it;
- else we use the short filename.
- */
-
- char *choosefname(direntry)
- struct direntry *direntry;
- {
- char *retptr; /* pointer to name that we will return */
- switch (direntry->system_id) {
- case SYSID_NIX:
- case SYSID_PORTABLE:
- case SYSID_MS:
- retptr = (direntry->namlen > 0) ? direntry->lfname : direntry->fname;
- break;
- default:
- retptr = direntry->fname;
- break;
- }
- return (retptr);
- } /* choosefname() */
-
- /*
- combine() combines a directory name and a filename, making sure the
- two are separated by a path separator
- */
- char *combine(result, dirname, fname)
- char result[], *dirname, *fname;
- {
- *result = '\0';
- if (*dirname != '\0') {
- strcpy(result, dirname);
- if (*lastptr(result) != *PATH_CH)
- strcat(result, PATH_CH);
- }
- strcat(result, fname);
- return (result);
- }
-
- /*
- fullpath() accepts a pointer to a directory entry and returns the
- combined directory name + filename. The long filename is used
- if available, else the short filename is used.
- */
- char *fullpath (direntry)
- struct direntry *direntry;
- {
- static char result[PATHSIZE];
- combine (result,
- direntry->dirlen > 0 ? direntry->dirname : "",
- (direntry->namlen > 0) ? direntry->lfname : direntry->fname
- );
- return (result);
- }
-
- /*
- ver_too_high returns true if version of provided archive header is
- too high for us to manipulate archive
- */
-
- int ver_too_high (header)
- struct zoo_header *header;
- {
- return (header->major_ver > MAJOR_VER ||
- (header->major_ver == MAJOR_VER &&
- header->minor_ver > MINOR_VER));
- }
-
- /*
- rwheader() reads archive header, checks consistency, makes sure its
- version number is not too high, updates it if too low, and seeks to
- beginning of first directory entry
- */
-
- rwheader (header, zoo_file)
- register struct zoo_header *header;
- FILE *zoo_file;
- {
-
- frd_zooh (header, zoo_file);
-
- if ((header->zoo_start + header->zoo_minus) != 0L)
- prterror ('f', failed_consistency);
- if (ver_too_high (header))
- prterror ('f', wrong_version, header->major_ver, header->minor_ver);
-
- /* We reach here if the archive version is not too high. Now, if it
- isn't the same as ours, we bring it up to ours so the modified archive
- will be safe from previous versions of Zoo */
-
- if (header->major_ver != MAJOR_VER || header->minor_ver != MINOR_VER) {
- header->major_ver = MAJOR_VER;
- header->minor_ver = MINOR_VER;
- fseek (zoo_file, 0L, 0); /* seek to beginning */
- fwr_zooh (header, zoo_file);
- }
- fseek (zoo_file, header->zoo_start, 0); /* seek to where data begins */
- } /* rwheader */
-
- /*
- writedir() write a directory entry with keyboard interrupt disabled
- */
- void writedir (direntry, zoo_file)
- struct direntry *direntry;
- FILE *zoo_file;
- {
- #ifndef NOSIGNAL
- int (*oldsignal)();
- oldsignal = signal (SIGINT, SIG_IGN);
- #endif
- if (fwr_dir (direntry, zoo_file) == -1)
- prterror ('f', disk_full);
- #ifndef NOSIGNAL
- signal (SIGINT, oldsignal);
- #endif
- }
-
- /*
- readdir() reads a directory entry from an archive. If the directory
- entry is invalid and if fail is 1, it causes a fatal error;
- else it returns. Return value is 0 if no error else -1;
- */
-
- int readdir (direntry, zoo_file, fail) /* read directory entry */
- register struct direntry *direntry;
- FILE *zoo_file;
- int fail; /* 0 -> return, 1 -> abort on error */
- {
- if (frd_dir (direntry, zoo_file) < 0) {
- if (fail)
- prterror ('f', bad_directory);
- else
- return (-1);
- }
- if (direntry->zoo_tag != ZOO_TAG) {
- if (fail)
- prterror ('f', bad_directory);
- else
- return (-1);
- }
- return (0);
- }
-
- /* use pointer version below */
- #ifdef COMMENT
- /* instr() searches a string for a substring */
- instr (s, t) /* return index of string t in string s, -1 if none */
- char s[], t[]; /* .. from K&R page 67 */
- {
- int i;
- register int j, k;
- for (i = 0; s[i] != '\0'; i++) {
- for (j = i, k = 0; t[k] != '\0' && s[j]==t[k]; j++, k++)
- ;
- if (t[k] == '\0')
- return (i);
- }
- return (-1);
- }
- #endif COMMENT
-
- /* instr() searches a string for a substring */
- /* from J. Brian Waters */
- int instr (s, t) /* return the position of t in s, -1 if none */
- char *s, *t; /* a pointer version of K&R index function p.67 */
- { /* renamed to instr() to avoid conflicts with C RTL - JBW */
-
- register char *i, *j, *k;
-
- for (i = s; *i; i++) {
- for (j = i, k = t; (*k) && (*j++ == *k); k++)
- ;
- if (!*k)
- return ((int) (i - s));
- }
- return(-1);
- }
-
- /* cfactor() calculates the compression factor given a directory entry */
- int cfactor (org_size, size_now)
- long org_size, size_now;
- {
- register int size_factor;
- if ((unsigned long) org_size > 1000000) { /* avoid later overflow */
- org_size = (unsigned long) org_size / 1024;
- size_now = (unsigned long) size_now / 1024;
- }
- if (org_size == 0) /* avoid division by zero */
- size_factor = 0;
- else {
- size_factor =
- (
- (1000 *
- ((unsigned long) org_size - (unsigned long) size_now)
- ) / org_size + 5
- ) / 10;
- }
- return (size_factor);
- }
-
- #ifndef STRDUP
- /***********
- strdup() duplicates a string using dynamic memory.
- */
-
- char *strdup (str)
- register char *str;
- {
- return (strcpy (emalloc (strlen(str)+1), str));
- }
- #endif /* STRDUP */
-
- /**************
- cmpnum() compares two pairs of unsigned integers and returns a negative,
- zero, or positive value as the comparison yields less than, equal, or
- greater than result. Each pair of unsigned integers is considered to be the
- more significant and the less significant half of a longer unsigned number.
-
- Note: cmpnum is used to compare dates and times.
- */
-
- int cmpnum (hi1, lo1, hi2, lo2)
- register unsigned int hi1, hi2;
- unsigned int lo1, lo2;
- {
- if (hi1 != hi2)
- return ((int) hi1 - hi2);
- else
- return ((int) lo1 - lo2);
- }
-
- /*******************/
- /* writenull() */
- /* writes a null directory entry to the archive whose handle is supplied */
- void writenull(handle, length)
- int handle, length;
- {
- #ifndef NOSIGNAL
- int (*oldsignal)();
- #endif
- struct direntry newentry;
- memset ((char *) &newentry, 0, sizeof (newentry));
- newentry.zoo_tag = ZOO_TAG;
- newentry.type = 2;
- /* Force entry to be the required length plus possibly 2 stray bytes
- by dividing up the needed padding into dirlen and namlen. */
- if (length > SIZ_DIRL)
- newentry.dirlen = newentry.namlen = (length-SIZ_DIRL)/2 + 2;
- else
- newentry.dirlen = newentry.namlen = 0;
- #ifndef NOSIGNAL
- oldsignal = signal (SIGINT, SIG_IGN);
- #endif
- if (wr_dir (&newentry, handle) == -1)
- prterror ('f', disk_full);
- #ifndef NOSIGNAL
- signal (SIGINT, oldsignal);
- #endif
- }
-
- #ifdef FORCESLASH
- /*******************/
- /*
- fixslash() changes all "\" characters in the supplied string to "/".
- */
-
- void fixslash (str)
- char *str;
- {
- register char *p;
- for (p = str; *p != '\0'; p++)
- if (*p == '\\')
- *p = '/';
- }
- #endif /* FORCESLASH */
-
- /* Currently using portable directory I/O for MSC also */
- #ifdef COMMENT
- #ifndef PORTABLE
- /* portable implementations are elsewhere */
- /***********************
- Function fwr_dir() writes a directory entry to a FILE. Return value is -1 on
- error, else 0.
- */
- int fwr_dir(direntry, zoo_file)
- struct direntry *direntry;
- FILE *zoo_file;
- {
- if (fwrite ((char *) direntry, SIZ_DIR, 1, zoo_file) != 1)
- return (-1);
- else
- return (0);
- }
-
- /***********************
- Function wr_dir() writes a directory entry to a handle. Return value is -1
- on error else 0.
- */
- int wr_dir(direntry, zoo_han)
- struct direntry *direntry;
- int zoo_han;
- {
- if (write (zoo_han, (char *) direntry, SIZ_DIR) != SIZ_DIR)
- return (-1);
- else
- return (0);
- }
-
- /***********************
- Function wr_zooh() writes an archive header to a handle. Return value -1 if
- error else 0.
- */
- int wr_zooh(zoo_header, zoo_han)
- struct zoo_header *zoo_header;
- int zoo_han;
- {
- if (write (zoo_han, (char *) zoo_header, SIZ_ZOOH) != SIZ_ZOOH)
- return (-1);
- else
- return (0);
- }
-
- /***********************
- Function fwr_zooh() writes an archive header to a FILE. Return value is -1
- if error else 0.
- */
- int fwr_zooh(zoo_header, zoo_file)
- struct zoo_header *zoo_header;
- FILE *zoo_file;
- {
- if (fwrite ((char *) zoo_header, SIZ_ZOOH, 1, zoo_file) != 1)
- return (-1);
- else
- return (0);
- }
- #endif /* end of not PORTABLE */
- #endif /* COMMENT */
-
-